package cn.aws360.boot.system.biz.service.impl;

import cn.aws360.boot.base.api.constant.enums.DelFlagEnum;
import cn.aws360.boot.base.api.exception.ServiceException;
import cn.aws360.boot.data.api.constant.DataConstant;
import cn.aws360.boot.data.api.factory.PageFactory;
import cn.aws360.boot.data.api.pojo.request.PageQuery;
import cn.aws360.boot.data.api.pojo.response.PageResult;
import cn.aws360.boot.data.api.utils.PojoUtils;
import cn.aws360.boot.system.api.constant.SysConstant;
import cn.aws360.boot.system.api.exception.SysExceptionEnum;
import cn.aws360.boot.system.api.pojo.request.SysDictItemQuery;
import cn.aws360.boot.system.api.pojo.request.SysDictItemWrite;
import cn.aws360.boot.system.api.pojo.response.SysDictItemModel;
import cn.aws360.boot.system.biz.domain.SysDictItem;
import cn.aws360.boot.system.biz.mapper.SysDictItemMapper;
import cn.aws360.boot.system.biz.service.SysDictItemService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author junnan
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysDictItemServiceImpl extends ServiceImpl<SysDictItemMapper, SysDictItem> implements SysDictItemService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = SysConstant.MODULE_DICT_CACHE, allEntries = true)
    public Boolean add(SysDictItemWrite sysDictItemWrite) {
        SysDictItem sysDictItem = BeanUtil.copyProperties(sysDictItemWrite, SysDictItem.class, DataConstant.ID);
        return this.save(sysDictItem);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = SysConstant.MODULE_DICT_CACHE, allEntries = true)
    public Boolean edit(SysDictItemWrite sysDictItemWrite) {
        SysDictItem sysDictItem = this.getSysDictItemById(sysDictItemWrite.getId());
        BeanUtil.copyProperties(sysDictItemWrite, sysDictItem);
        return this.updateById(sysDictItem);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = SysConstant.MODULE_DICT_CACHE, allEntries = true)
    public Boolean remove(String ids) {
        List<Integer> itemIdList = Convert.toList(Integer.class, ids.split(StrUtil.COMMA));
        return this.removeByIds(itemIdList);
    }

    @Override
    public SysDictItemModel detail(Integer id) {
        SysDictItem sysDictItem = this.getSysDictItemById(id);
        return BeanUtil.copyProperties(sysDictItem, SysDictItemModel.class);
    }

    @Override
    public List<SysDictItemModel> findList(SysDictItemQuery sysDictItemQuery) {
        LambdaQueryWrapper<SysDictItem> queryWrapper = createQueryWrapper(sysDictItemQuery);
        List<SysDictItem> sysDictItemList = this.list(queryWrapper);
        return PojoUtils.copyToList(sysDictItemList, SysDictItemModel.class);
    }

    @Override
    public PageResult<SysDictItemModel> findPage(SysDictItemQuery sysDictItemQuery, PageQuery pageQuery) {
        LambdaQueryWrapper<SysDictItem> queryWrapper = createQueryWrapper(sysDictItemQuery);
        PageResult<SysDictItem> sysDictItemPage = PageFactory.getPageResult(this, pageQuery, queryWrapper);
        return PojoUtils.copyToPage(sysDictItemPage, SysDictItemModel.class);
    }

    private SysDictItem getSysDictItemById(Integer id) {
        SysDictItem sysDictItem = this.getById(id);
        checkNotExist(sysDictItem);
        return sysDictItem;
    }

    private LambdaQueryWrapper<SysDictItem> createQueryWrapper(SysDictItemQuery itemQuery) {
        return Wrappers.<SysDictItem>lambdaQuery()
                .eq(ObjectUtil.isNotNull(itemQuery.getPid()), SysDictItem::getPid, itemQuery.getPid())
                .like(ObjectUtil.isNotEmpty(itemQuery.getLabel()), SysDictItem::getLabel, itemQuery.getLabel())
                .orderByAsc(SysDictItem::getSort);
    }

    private void checkNotExist(SysDictItem sysDictItem) {
        if (ObjectUtil.isNull(sysDictItem) || DelFlagEnum.Y.getValue().equals(sysDictItem.getDelFlag())) {
            throw new ServiceException(SysExceptionEnum.DICT_ITEM_NOT_EXIST);
        }
    }

}
